3 use Wikimedia\TestingAccessWrapper
;
7 * @covers MessageBlobStore
9 class MessageBlobStoreTest
extends PHPUnit\Framework\TestCase
{
11 use MediaWikiCoversValidator
;
13 protected function setUp() {
15 // MediaWiki tests defaults $wgMainWANCache to CACHE_NONE.
16 // Use hash instead so that caching is observed
17 $this->wanCache
= $this->getMockBuilder( WANObjectCache
::class )
18 ->setConstructorArgs( [ [
19 'cache' => new HashBagOStuff(),
21 'relayer' => new EventRelayerNull( [] )
23 ->setMethods( [ 'makePurgeValue' ] )
26 $this->wanCache
->expects( $this->any() )
27 ->method( 'makePurgeValue' )
28 ->will( $this->returnCallback( function ( $timestamp, $holdoff ) {
29 // Disable holdoff as it messes with testing
30 return WANObjectCache
::PURGE_VAL_PREFIX
. (float)$timestamp . ':0';
34 protected function makeBlobStore( $methods = null, $rl = null ) {
35 $blobStore = $this->getMockBuilder( MessageBlobStore
::class )
36 ->setConstructorArgs( [ $rl ] )
37 ->setMethods( $methods )
40 $access = TestingAccessWrapper
::newFromObject( $blobStore );
41 $access->wanCache
= $this->wanCache
;
45 protected function makeModule( array $messages ) {
46 $module = new ResourceLoaderTestModule( [ 'messages' => $messages ] );
47 $module->setName( 'test.blobstore' );
51 /** @covers MessageBlobStore::setLogger */
52 public function testSetLogger() {
53 $blobStore = $this->makeBlobStore();
54 $this->assertSame( null, $blobStore->setLogger( new Psr\Log\
NullLogger() ) );
57 /** @covers MessageBlobStore::getResourceLoader */
58 public function testGetResourceLoader() {
59 // Call protected method
60 $blobStore = TestingAccessWrapper
::newFromObject( $this->makeBlobStore() );
61 $this->assertInstanceOf(
62 ResourceLoader
::class,
63 $blobStore->getResourceLoader()
67 /** @covers MessageBlobStore::fetchMessage */
68 public function testFetchMessage() {
69 $module = $this->makeModule( [ 'mainpage' ] );
70 $rl = new ResourceLoader();
71 $rl->register( $module->getName(), $module );
73 $blobStore = $this->makeBlobStore( null, $rl );
74 $blob = $blobStore->getBlob( $module, 'en' );
76 $this->assertEquals( '{"mainpage":"Main Page"}', $blob, 'Generated blob' );
79 /** @covers MessageBlobStore::fetchMessage */
80 public function testFetchMessageFail() {
81 $module = $this->makeModule( [ 'i-dont-exist' ] );
82 $rl = new ResourceLoader();
83 $rl->register( $module->getName(), $module );
85 $blobStore = $this->makeBlobStore( null, $rl );
86 $blob = $blobStore->getBlob( $module, 'en' );
88 $this->assertEquals( '{"i-dont-exist":"\u29fci-dont-exist\u29fd"}', $blob, 'Generated blob' );
91 public function testGetBlob() {
92 $module = $this->makeModule( [ 'foo' ] );
93 $rl = new ResourceLoader();
94 $rl->register( $module->getName(), $module );
96 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
97 $blobStore->expects( $this->once() )
98 ->method( 'fetchMessage' )
99 ->will( $this->returnValue( 'Example' ) );
101 $blob = $blobStore->getBlob( $module, 'en' );
103 $this->assertEquals( '{"foo":"Example"}', $blob, 'Generated blob' );
106 public function testGetBlobCached() {
107 $module = $this->makeModule( [ 'example' ] );
108 $rl = new ResourceLoader();
109 $rl->register( $module->getName(), $module );
111 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
112 $blobStore->expects( $this->once() )
113 ->method( 'fetchMessage' )
114 ->will( $this->returnValue( 'First' ) );
116 $module = $this->makeModule( [ 'example' ] );
117 $blob = $blobStore->getBlob( $module, 'en' );
118 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
120 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
121 $blobStore->expects( $this->never() )
122 ->method( 'fetchMessage' )
123 ->will( $this->returnValue( 'Second' ) );
125 $module = $this->makeModule( [ 'example' ] );
126 $blob = $blobStore->getBlob( $module, 'en' );
127 $this->assertEquals( '{"example":"First"}', $blob, 'Cache hit' );
130 public function testUpdateMessage() {
131 $module = $this->makeModule( [ 'example' ] );
132 $rl = new ResourceLoader();
133 $rl->register( $module->getName(), $module );
134 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
135 $blobStore->expects( $this->once() )
136 ->method( 'fetchMessage' )
137 ->will( $this->returnValue( 'First' ) );
139 $blob = $blobStore->getBlob( $module, 'en' );
140 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
142 $blobStore->updateMessage( 'example' );
144 $module = $this->makeModule( [ 'example' ] );
145 $rl = new ResourceLoader();
146 $rl->register( $module->getName(), $module );
147 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
148 $blobStore->expects( $this->once() )
149 ->method( 'fetchMessage' )
150 ->will( $this->returnValue( 'Second' ) );
152 $blob = $blobStore->getBlob( $module, 'en' );
153 $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );
156 public function testValidation() {
157 $module = $this->makeModule( [ 'foo' ] );
158 $rl = new ResourceLoader();
159 $rl->register( $module->getName(), $module );
161 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
162 $blobStore->expects( $this->once() )
163 ->method( 'fetchMessage' )
164 ->will( $this->returnValueMap( [
165 [ 'foo', 'en', 'Hello' ],
168 $blob = $blobStore->getBlob( $module, 'en' );
169 $this->assertEquals( '{"foo":"Hello"}', $blob, 'Generated blob' );
171 // Now, imagine a change to the module is deployed. The module now contains
172 // message 'foo' and 'bar'. While updateMessage() was not called (since no
173 // message values were changed) it should detect the change in list of
175 $module = $this->makeModule( [ 'foo', 'bar' ] );
176 $rl = new ResourceLoader();
177 $rl->register( $module->getName(), $module );
179 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
180 $blobStore->expects( $this->exactly( 2 ) )
181 ->method( 'fetchMessage' )
182 ->will( $this->returnValueMap( [
183 [ 'foo', 'en', 'Hello' ],
184 [ 'bar', 'en', 'World' ],
187 $blob = $blobStore->getBlob( $module, 'en' );
188 $this->assertEquals( '{"foo":"Hello","bar":"World"}', $blob, 'Updated blob' );
191 public function testClear() {
192 $module = $this->makeModule( [ 'example' ] );
193 $rl = new ResourceLoader();
194 $rl->register( $module->getName(), $module );
195 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
196 $blobStore->expects( $this->exactly( 2 ) )
197 ->method( 'fetchMessage' )
198 ->will( $this->onConsecutiveCalls( 'First', 'Second' ) );
200 $blob = $blobStore->getBlob( $module, 'en' );
201 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
203 $blob = $blobStore->getBlob( $module, 'en' );
204 $this->assertEquals( '{"example":"First"}', $blob, 'Cache-hit' );
208 $blob = $blobStore->getBlob( $module, 'en' );
209 $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );